--editing for triple vertical, with a kinesis advantage.

-- Welcome to Digit's Nice Minimal Tabular Boonad
-- takes some cues from clfswm and i3
-- Digit can usually be found in #witchlinux on irc.freenode.net
-- GNU GPL, yo!

-- comments should help keep things clear.  for example, "-- artistgamer" refers to the keybind layout suited to one hand on the mouse, using wsad instead of hjkl.  other comments are mostly self explanitory, or explained elsewhere.  some will point you to xmonad.org for more information.

-- this is still in development, but the general jist is in place.  there are still MANY features intended to be added at this stage.  - 2013-03-25

-- 2016 saw a change in hardware arangement.  now triple monitors are vertical, some changes to layouts so it works better with large numbers of windows.
-- -- still never sussed getting tabs coloured as intended.
     
{-# LANGUAGE NoMonomorphismRestriction #-} -- for gridselect customisation
import XMonad  hiding ( (|||) )
--import XMonad.Core -- as XMonad hiding ( (|||) )
--    (workspaces,manageHook,keys,logHook,startupHook,borderWidth,mouseBindings
--    ,layoutHook,modMask,terminal,normalBorderColor,focusedBorderColor,focusFollowsMouse
--    ,handleEventHook,clickJustFocuses)
import XMonad.Layout.LayoutCombinators -- hiding ( (|||) )
import XMonad.Util.EZConfig -- allows all kinds, like automated emacs submaps
import XMonad.Actions.Submap -- allows emacs-like keys
import XMonad.Layout.Tabbed -- obvious integral for the TabularBoonad
--import XMonad.Layout.Grid -- yus
--import XMonad.Layout.HintedGrid --trying to get a better alt grid for more 4:3 ratio
import XMonad.Layout.GridVariants --2nd attempt at better grid layout. fingers crossed no more vert-letter-boxes.
import XMonad.Layout.OneBig -- yus
import qualified XMonad.StackSet as W -- does something important i'm sure.
import XMonad.Actions.CycleWS -- gets around
import XMonad.Layout.NoBorders -- prettier when fullscreen
import XMonad.Layout.MultiToggle -- allows fullscreen toggle, without Full layout
import XMonad.Layout.MultiToggle.Instances --
import XMonad.Layout.MouseResizableTile -- for djtsotherlayoutHook, developing alt toggle. 2018 layout curiosities
import XMonad.Actions.DynamicWorkspaces -- hrmm, is this where withNthWorkspace came from... curious.
import XMonad.Actions.CopyWindow(copy) --this too?
--sublayoutstuff http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Layout-SubLayouts.html
import XMonad.Layout.SubLayouts -- oh this makes it oh so sexy.
import qualified XMonad.Layout.WindowNavigation as WN -- hrmm kinda essential, it seems.
import XMonad.Layout.BoringWindows -- not so boring, proves handy.  make it so.
-- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Actions-GridSelect.html
import XMonad.Actions.GridSelect -- adds that gui selection menu 2d map thingy
--import XMonad.StackSet as W -- scratchpad (already got, above)
import XMonad.ManageHook -- scratchpad
import XMonad.Util.NamedScratchpad -- scratchpad
import XMonad.Layout.Stoppable -- curious https://hackage.haskell.org/package/xmonad-contrib-0.13/docs/XMonad-Layout-Stoppable.html 2018 layout curiosities
import XMonad.Layout.Simplest --2018 layout curiosities
import XMonad hiding ((|||)) --2018 layout curiosities - multi layout cycle binds - hackage.haskell.org/package/xmonad-contrib-0.13/docs/XMonad-Actions-CycleSelectedLayouts.html#g:1
import XMonad.Layout.LayoutCombinators ((|||)) --2018 layout curiosities - multi layout cycle binds - 
import XMonad.Actions.CycleSelectedLayouts --2018 layout curiosities - multi layout cycle binds - 

main = xmonad $ defaultConfig
     { modMask = mod4Mask -- use tux instead of alt, which is M1(/mod1)
     , terminal = "rxvt-unicode" -- was "xterm"
     , normalBorderColor  = "#487855" --487855 mk1 of "inteligent green"
     , focusedBorderColor = "#ff6900"
     , keys = djtemacsKeys
     , layoutHook = djtslayoutHook
--     , layoutHook = djtsotherlayoutHook -- 2018 layout curiousities
     , workspaces = djtWorktops
     , manageHook = namedScratchpadManageHook scratchpads
--     , XMonad.clickJustFocuses = djtsclickJustFocuses
     } -- `additionalKeysP` djtemacsKeys

--djtsclickJustFocuses :: Bool
--djtsclickJustFocuses = False

-- get this working... get it implimented in main, right?
djtsTabConfig = defaultTheme { inactiveBorderColor = "#FF0000"
                                   , activeTextColor = "#00FF00"}

djtslayoutHook = smartBorders 
                 $ WN.windowNavigation 
                 $ subTabbed 
                 $ boringWindows 
                 $
                 mkToggle (MIRROR ?? NOBORDERS ?? FULL ?? EOT) (Grid (55/34) ||| OneBig (5/8) (3/5) ||| OneBig (3/4) (3/4))
                 
djtsotherlayoutHook = smartBorders -- 2018 layout curiosities
                      $ WN.windowNavigation 
                      $ subTabbed
                      $ boringWindows
                      $
                      mkToggle (MIRROR ?? NOBORDERS ?? FULL ?? EOT) (Grid (55/34) ||| mouseResizableTile ||| stoppable Simplest) -- 2018 layout curiosities
-- the standard `Choose` layout constucted by using (|||) has more Messages than I realised, so you should be able to just use that, ensuring that your two groups of layouts are at the top level, e.g.: (l1 ||| l2 ||| l3) ||| (r1 ||| r2 ||| r3) -- from Lears in #xmonad when asking how to alt-tab n alt-space for the two distinct layoutHook cyclings

djtWorktops  = ["1","2","3","4","5","6","7","8","9"]

-- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Actions-GridSelect.html
--gsconfig1 = defaultGSConfig { gs_cellheight = 19, gs_cellwidth = 144 }
gsconfig2 colorizer = (buildDefaultGSConfig colorizer) { gs_cellheight = 42, gs_cellwidth = 180 }

{-gsconfig3 = defaultGSConfig
   { gs_cellheight = 30
   , gs_cellwidth = 100
   , gs_navigate = myNavigation
   }
-}

-- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Util-NamedScratchpad.html
scratchpads = [
-- run htop in term, top half, perfect fit.
    NS "ttyload" "xterm -e ttyload" (title =? "ttyload") 
        (customFloating $ W.RationalRect (0/1) (0/1) (1/1) (1/2)) ,
-- run htop in term, top half, perfect fit.
    NS "htop" "xterm -e htop" (title =? "htop")  
        (customFloating $ W.RationalRect (0/1) (0/1) (1/1) (1/2)) ,
-- run alsamixer in term, bottom half of screen space around edge. 
    NS "alsamixer" "xterm -e alsamixer" (title =? "alsamixer") 
        (customFloating $ W.RationalRect (1/100) (49/100) (98/100) (1/2)) ,
-- run emacs bottom half of screen space around edge. 
    NS "emacs" "emacs" (className =? "Emacs") 
        (customFloating $ W.RationalRect (1/100) (49/100) (98/100) (1/2)) ,
-- drop-down terminal    like yeahconsole/tilda/guake/yakuake
--    NS "xterm" "xterm -e tmux" (title =? "tmux")
--        (customFloating $ W.RationalRect (0/1) (0/1) (1/1) (1/2)) ,
-- drop-down terminalMK2
    NS "terminology" "terminology -e tmux" (className =? "terminology")
        (customFloating $ W.RationalRect (0/1) (0/1) (1/1) (1/2)) ,
-- pop bigbrowser
--    NS "firefox" "firefox" (className =? "Firefox")
    NS "firefox" "iceweasel" (className =? "Firefox")    
        (customFloating $ W.RationalRect (0/1) (0/1) (1/1) (1/2)) ,
-- pop-in terminal chat    like above, but one for chat.    
    NS "chat" "iirc" (title =? "chat")
        (customFloating $ W.RationalRect (0/1) (0/1) (1/2) (1/2))
    ] where role = stringProperty "WM_WINDOW_ROLE"

djtemacsKeys = \c -> mkKeymap c $
     [ ("M-S-<Return>", spawn $ terminal c) --but why bother, with yeahconsole or scratchpads ;)
--some conventional focus changing keybinds are still here, but de-emphasised, as focus would nominally be changed with mouse using this setup
--     , ("M-S-<Space>", setLayout djtslayoutHook) -- %!  Reset the layouts on the current workspace to default
     , ("M-S-<Space>", refresh) -- incase stuff gets messy. ^and cos i cant get reset to work.  tried ways.
--     , ("M-x o", spawn "xteddy")  -- type mod+x then o.   y it no work?
     , ("M-<F11>", sendMessage $ Toggle FULL) --fullscreen toggle.  yus.
     , ("M-S-<F11>", sendMessage $ Toggle MIRROR) --mirror toggle.  yus yus.
     , ("M-g", sendMessage $ Toggle FULL) --artistgamer --fullscreen toggle. yus.
     , ("M-S-g", sendMessage $ Toggle MIRROR) --artistgamer --mirror toggle.  yus yus.
     , ("M-<F4>", kill) --close a window
     , ("M-<F6>", spawn "xkill") -- no, srsly, close it! (click window to kill)
     , ("M-q", spawn "xmonad --recompile && xmonad --restart") --try config changes
--     , ("M-S-q", io (exitWith ExitSuccess)) --meh, dont need, myt slip n press.
     , ("M-C-<Tab>", goToSelected defaultGSConfig) --artistgamer gridselect open windows
--     , ("M-r", spawn "dmenu_run")
     , ("M-r", spawn "~/bin/dmenu-bind.sh")  
--     , ("M-r", spawn "~/.config/dmenu/dmenu-bind.sh") --artistgamer
--     , ("M-C-r", spawnSelected defaultGSConfig ["gimp","mypaint","inkscape","blender","freecad","iceape","lmms","hydrogen","audacity","pitivi","synfigstudio","minitube","clementine","transmission-gtk","gcolor2","fontforge","openshot","pitivi","avidemux","aemenu", "smplayer2", "vlc"]) --artistgamer gridselect launcher
     , ("M-C-r", spawnSelected defaultGSConfig ["gimp","blender","freecad","lmms","hydrogen","audacity","synfigstudio","gcolor2","fontforge","lxappearance","leafpad"]) --artistgamer gridselect launcher
--     , ("M-<F2>", spawn "~/.config/dmenu/dmenu-bind.sh") --oldskool
--     , ("M-A-r", spawn "gmrun") --artistgamer
--     , ("M-<F3>", spawn "gmrun") --oldskool
--     , ("<Menu>", spawn "8menu")
--     , ("M-<Menu>", spawn "dmenu-bind.sh")
--     , ("M-x", spawn "aemenu") --artistgamer 
--     , ("M-x", spawn "qmenu") --artistgamer -- points to script starting a menu
     , ("M-<Space>", sendMessage NextLayout) --cycle between layouts
     , ("M-e", windows W.focusUp) --artistgamer
     , ("M-d", windows W.focusDown) --artistgamer
     , ("M-C-s", sendMessage $ pullGroup WN.L) --sublayout --artistgamer --merge left to tab stack
     , ("M-C-f", sendMessage $ pullGroup WN.R) --sublayout --artistgamer --merge right to tab stack
     , ("M-C-e", sendMessage $ pullGroup WN.U) --sublayout --artistgamer --merge up to tab stack
     , ("M-C-d", sendMessage $ pullGroup WN.D) --sublayout --artistgamer --merge down to tab stack
     , ("S-M-e", windows W.swapUp) --artstgamer
     , ("S-M-d", windows W.swapDown) --artstgamer
     , ("M-w", windows W.swapMaster) -- move focused window to master pane --exhibit/enter     
     , ("M-C-w", withFocused (sendMessage . UnMerge)) --sublayout --artistgamer --exit/escape
     , ("M-C-S-w", withFocused (sendMessage . MergeAll)) --sublayout --artstgamer --entanglement
       -- changing to have xcv be the triple monitor keys
     , ("M-c", prevWS) --artstgamer previous workspace
       -- changing to have xcv be the triple monitor keys
     , ("M-v", nextWS) --artstgamer next workspace
       -- changing to have xcv be the triple monitor keys
     , ("S-M-c", shiftToPrev) --artstgamer move focussed window to previous workspace
       -- changing to have xcv be the triple monitor keys       
     , ("S-M-v", shiftToNext) --artstgamer move focussed window to next workspace
--     , ("M-<Tab>", windows W.focusDown) -- focus next window --or use mouse -- changing 4 2018layoutexperiment2, djtsotherlayoutHook
--     , ("M-S-<Tab>", windows W.focusUp  ) -- focus previous window --or use mouse -- changing 4 2018layoutexperiment2, djtsotherlayoutHook
--     , ("M-<Tab>",  ------- fix me!  to cycle through djtsotherlayoutHook
     , ("M-<Tab>", cycleThroughLayouts ["FULL", "MirrorTall"])
     , ("M-t", withFocused $ windows . W.sink) -- re-tile floated window
--     , ("M-C-<Period>", onGroup W.focusUp') --sublayout --not sure wtf anymore
--     , ("M-C-<Comma>", onGroup W.focusDown') --sublayout --not sure wtf anymore
       -- and the boring windows:, ((modm, xK_j), focusDown) -- wtf to implement?
       -- and the boring windows:, ((modm, xK_k), focusUp) -- wtf to implement?
--     , ("M-S-<space>", setLayout $ XMonad.layoutHook conf) --rly need dat?
-- namedscratchpad keybinds     
--     , ("<F12>", namedScratchpadAction scratchpads "xterm") -- xmoake scratchpad
     , ("M-p", spawn "pron") --pronigator
     , ("<F12>", namedScratchpadAction scratchpads "terminology") --mk2
     , ("M-<F1>", namedScratchpadAction scratchpads "emacs") --emacs
     , ("M-<F2>", namedScratchpadAction scratchpads "firefox") --firefox
     , ("M-<F7>", namedScratchpadAction scratchpads "ttyload") -- scratchpad 
     , ("M-<F8>", namedScratchpadAction scratchpads "htop") -- scratchpad 
     , ("M-<F9>", namedScratchpadAction scratchpads "alsamixer") -- scratchpad 
     , ("M-<F11>", namedScratchpadAction scratchpads "iirc")  --scratchpad
     ]
     ++
     -- (2012-09-29 15:14:37) dr_bs: 
     zip (map (\x -> fst x++[snd x]) ((zip (repeat "M-") (['1'..'9'])))) (map (withNthWorkspace W.greedyView) [0..])

     ++
     -- so i extrapolate from dr_bs's above, and from 
     -- http://xmonad.org/xmonad-docs/xmonad-contrib/XMonad-Actions-DynamicWorkspaces.html
     zip (map (\x -> fst x++[snd x]) ((zip (repeat "M-S-") (['1'..'9'])))) (map (withNthWorkspace W.shift) [0..])
     
